//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

var str1 = "HelloWorld"


//常量定义  给常量一个值

let pai = 3.1415926

//变量 主动变更的，睡觉，加班时间

//如何正确使用常量与变量？? 1.总是优先使用常量 2.交给编译器决定

var string = "老司机带你swift上车"

//值的类型和类型推断
var 今天开车 : Int = 5
var car1 = 5
//可以省类型判断 5公里 直接是Int 类型


//Double类型 双精度类型 swift中默认浮点型是Double(双精度)
var oneWater = 3.5
var oneWater1 : Double = 3.5

//类型安全
//1.变量一旦定义，其类型不可更改:即 不能给变量一个类型不同的值
var 电费 = 3.5
电费 = 5
//X -电费 = "五毛"  //error :'String' to type 'Double'
print(电费)

//Bool 布尔型

// 布尔型 : Bool 逻辑上真或假

var  资金充足情况 : Bool = true
资金充足情况 = false

var vip = false

vip = true

//Mark : Tuple 元组 ：定义变量的一个组合

var x = 1
var y = 2
var z = 3

var 向量 = (1,2,3)
向量.0
向量.1
向量.2

//获取其中的某个值，用序号与前缀

var (o,p,q) = (1,2,3)
o
p
q

var  课程名 = (day:3,unit:"天",lang:"swift",ver:"3.0")
课程名.day

//可选类型 Optional 代表变了可能有值的情况 
//性别 住址辅助,可有可无
//定义形式: var 变量 : 类型？默认是无值(nil)

var  addstr : String?
addstr = "南京雨花台区软件大道168号"

//基础操作符号
/**
1. + - * /
术语：操作几个对象，被称为几元操作符
操作一个目标，是一元操作符
**/

var  a01 = 6
let  b = -a01

//赋值操作符
//用等号 =
//数学操作符号

1 + 2
3 - 4
5 * 6
12 / 3
13 % 3

//组合赋值操作符
//+=
var i = 1
i += 2

//比较操作符

//> >= < <=  结果是 true or false

//逻辑操作符
// && || ！
// 与 或 非


//字符和字符串
//字符串就是一串文本
//string是字符串类型，
//character 是字符类型
//2个字符串可以通过+号链接
//通过字符串插值可合成一个成字符串

//"字符串"

var a1 = ""

var b2 = " "

//判断是否为null
a1.isEmpty

b2.isEmpty

var a : Character = "我"

//var b : Character = "hyl"   X

let  c = "老司机带路上车"

//c.characters //集合

for var character01 in c.characters {
    print(character01)
    dump(character01)
}

let  a12 = "小黄车"
let  b12 = "小绿车"
let  c12 = "小蓝车"

var  d123 = a12 + b12 + c12


//向字符串添加单个字符,用apppend方法

let number : Character = "1"

//d123 += number

d123 .append(number)



//综合
//字符串插值：组合常量／变量/字面量/表达式成一个长字符串

let name = "hyl"
let type = "D"
let number1 = 11
let price = 158.5

let 订票提示 = "\(name)先生,你订购的\(type)\(number)往返机票需要支付\(price*2)元."

// \()

//集合类型-数组


//集合类型
//Array 有序可重复
//Set   无序不重复
//Dictionary 无序可重复 但每个值有唯一的键
//
//批量处理集合中的元素，用for in 循环

//1.定义Array类型

let array100 : [Int]

//2.创建默认值的数组

array100 = [Int] (repeatElement(3, count: 10))

//3.创建一个有序范围的Int数组,Array(起始值...终止值）

let array2 = Array (1...10)

//4.用数组字面量来创建数组:[值1,值2,值3，...,值N]

var places = ["北京","上海","南京"]

//5.count 元素计数  空否:isEmpty
places.count
places.isEmpty
//添加一个元素城市
places.append("广州")
//加其他数组
let forPlaces = ["NewYork","London"]

places += forPlaces

//获取元素：数组名【索引】
places[1]
places[places.count-1]
places.last
places.first

//插入insert


places.insert("巴黎", at: places.endIndex)
places.insert("巴黎", at: places.startIndex)

places.insert("巴黎1", at: 2)

//移除 remove
places.remove(at: places.startIndex)
places

//5.集合类型-Set 不重复的，适合存唯一性的数据 用户名/身份证

//定义: Set<元素类型>,无法使用类型推断、可省略类型

let cardno : Set = [1,2,3,4,5,2]
cardno

//用数组字面量创建集合

var citys : Set = ["上海","上海1","上海2","上海3","上海4","上海5",]

citys.count

citys.isEmpty //集合不容许为null

citys.insert("南京")
citys

citys.remove("上海1")
citys

citys.contains("南京")

//转换为数组:sorted

let citysArray = citys.sorted()
citysArray

citysArray[0]


//集合间的运算:交叉并补

//交集 intersection  差集 subtract 并集 union 补集 symmetricDifference
//intersection

var x01 : Set = [1,2,3,4]
var y01 : Set = [3,4,5,6]

x01.intersection(y01)
x01.subtract(y01)
y01.subtract(x01)

x01.union(y01)

x01.symmetricDifference(y01)

//相等
let h : Set = [1,2,3]
let u : Set = [3,2,1,5]

h == u

//子集 isSubset  严格的子集isStrictSubset
h  .isSubset(of: u)
h .isStrictSubset(of: u)


//父集:isSuperset

u.isSuperset(of: h)

//无交集

let  zz : Set = [1,2,3]
let  xx : Set = [4,5]
zz.isDisjoint(with: xx)

//6.集合类型-字典 key-value 键值对
var originDr : Dictionary<String,String>
var Dr : [String:String]

var dir = ["name":"hyl","age":"18","sex":"Man"]
dir
dir.count
dir.isEmpty

//2.添加、更新 ：字典变量【键】 = 值
//dir["个性"] = "不男不女"

//3.获取下标
dir["sex"]
dir
//移除
dir["age"] = nil
print(dir)


for (key,value)  in dir {
    print(key,value)
}


for key in dir.keys {
    print(key)
}

for value in dir.values {
    print(value)
}

//7.控制流



//1.循环 控制 判断 switch
let spaceArr = ["beijing","上海","NewYork"]


for place in spaceArr {
    print(place)
}


var sum = 0

for i in 1...100 {
    sum += i
}

print(sum)

//如果只循环固定次数、省略项名

for _ in 1...100
{
 print("老司机")
}

//while 循环执行一系列操作，知道条件不成立
var w_i = 1
var sum_w = 0

while w_i <= 100 {
    sum_w += sum_w + 1
    w_i += 1
}

sum_w


//循环中判断
//continue
//break
//1.结束本次循环
//2.结束整个循环


//1.备注
//guard 早退语句,在必须条件不满足的早期阶段退出执行、语句关键词与if相似

var hasKey = true

var credit : Int? = 5

//guard hasKey else {
//    return
//}

func 打的() {
    guard hasKey else {
        return
    }
    guard let mycredit = credit ,mycredit >= 6 else
    {
        return
        }
    print("终于跳出来啦～")
}

//打的()

//switch 定义格式
//switch <#value#> {
//case <#pattern#>:
//    <#code#>
//default:
//    <#code#>
//}

//8.函数

//func 函数()
//函数()

//函数是一段代码快，执行特性的任务

//形式:
//func 函数名(参数1:类型,参数2:类型) -> 返回结果类型{执行语句}

//
//func addPlus(x: Int, y: Int) -> Int {
//    return x + y
//}

//
//var  zxx = addPlus(x: 4, y: 5)

//func  welcome {
//       print("无参数函数")
//}

//welcome()
//
func maxMin() -> (Int,Int) {
    return (Int.min ,Int.max)
}

maxMin().0
maxMin().1


//MARK : 函数式类型  函数式编程:(Int,Int) ->Int
func calculate(x:Int ,y:Int ,method:(Int,Int) ->Int) ->Int{
    return method(x, y)
}

func add(x:Int,y:Int) -> Int {
 
    return x + y
}


func multiply(x:Int,y:Int) -> Int{
 
    return x * y

}

calculate(x: 4, y: 5, method: add)

calculate(x: 4, y: 5, method: multiply)



//#Mark:闭包
//1.闭包就是没有名称的函数，省区函数吗，把参数和返回值放在花括号里面

var city = ["南京","厦门","连云港","郑州"]

//sorted 函数对数组进行排序。只接受一个函数参数



func daoxu(a:String,b:String) -> Bool {
    return a > b
}


var cityRank1 = city.sorted()

var cityRank2 = city.sorted(by: daoxu)


//2.闭包表达式改写:

var cityRank3 = city.sorted { (a, b) -> Bool in
   return  a > b
}

//2.闭包表达式自动推断:
var cityRank4 = city.sorted { (a, b) -> Bool in
      a > b  //单表达式可以省略return
}




//var cityRank5 = city.sorted {
//  return a > b  //单表达式可以省略return
//}

//可以使用快捷参数，前缀$,从0开始递增


var cityRank5 = city.sorted{$0 > $1}

cityRank5



//#Mark:枚举

//1.定义
enum weather {
    case sunny
    case cloudy
    case rainy
    case locauld
    case froggy
}

//2.用法
weather.sunny
weather.rainy

//3.场景
//switch 配合使用
var todayWeather = weather.froggy
//（1）
switch todayWeather {
case weather.froggy:
     print("今天天气有雾")
case weather.rainy:
    print("今天天气有雨")
default:
     print("今天天气晴朗")
}

//（2）.方式,可以省略枚举名
//switch todayWeather {
//case .froggy:
//    print("今天天气有雾")
//case .rainy:
//    print("今天天气有雨")
//default:
//    print("今天天气晴朗")
//}



























